﻿using System.Collections.Generic;
using System.ComponentModel;
using Dataweb.NShape.Advanced;
using Dataweb.NShape;
using cz.zcu.PreSti.Components;
using System.Drawing;
using System;

namespace cz.zcu.PreSti.Shapes
{
    public class ExponentialDistributionGeneratorSymbol : GeneratorSymbol
    {
        #region ISymbol Members

        public override BaseComponent initializeComponent(IPresentation p)
        {
            ExponentialDistributionGeneratorModel model = (ExponentialDistributionGeneratorModel)this.ModelObject;
            ExponentialDistributionGenerator generator = new ExponentialDistributionGenerator();
            generator.Variance = model.Variance;
            generator.CropSize = model.CropSize;
            generator.Translation = model.Translation;
            return generator;
        }

        #endregion

        protected internal ExponentialDistributionGeneratorSymbol(ShapeType shapeType, Template template)
            : base(shapeType, template)
        {
        }


        protected internal ExponentialDistributionGeneratorSymbol(ShapeType shapeType, IStyleSet styleSet)
            : base(shapeType, styleSet)
        {
        }

        public override Shape Clone()
        {
            Shape result = new ExponentialDistributionGeneratorSymbol(Type, (Template)null);
            result.CopyFrom(this);
            return result;
        }

        public override void CopyFrom(Shape source)
        {
            base.CopyFrom(source);
        }

        protected override void DrawIcon(Graphics graphics)
        {
            graphics.DrawImage(icons.exp, new Rectangle(X - Diameter / 2, Y - Diameter / 2, Diameter, Diameter));
        }

        internal static Shape CreateInstance(ShapeType shapeType, Template template)
        {
            return new ExponentialDistributionGeneratorSymbol(shapeType, template);
        }

    }

    public class ExponentialDistributionGeneratorModel : ModelObjectBase
    {

        #region Fields

        private double variance = 1;
        private double cropSize = 0;
        private double translation = 0;
        private char securityDomainName = 'A';

        private const int PropertyIdVariance = 1;
        private const int PropertyIdCropSize = 2;
        private const int PropertyIdTranslation = 3;

        #endregion

        #region properties

        [Category("Presentation")]
        [Description("The expected (mean) value of the square of the deviation of that variable from its expected value or mean")]
        [PropertyMappingId(PropertyIdVariance)]
        public virtual double Variance
        {
            get
            {
                return variance;
            }
            set
            {
                variance = value;
            }
        }

        [Category("Presentation")]
        [Description("Size of cropping area measured from 0 (zero) to the right. Values distanced from 0 for more than CropSize are omitted. 0 means no cropping applied.")]
        [PropertyMappingId(PropertyIdCropSize)]
        public virtual double CropSize
        {
            get
            {
                return cropSize;
            }
            set
            {
                cropSize = value;
            }
        }

        [Category("Presentation")]
        [Description("Translation of the exponential curve over x-axis. Translation is applied after cropping by CropSize value.")]
        [PropertyMappingId(PropertyIdTranslation)]
        public virtual double Translation
        {
            get
            {
                return translation;
            }
            set
            {
                translation = value;
            }
        }

        #endregion

        public static ExponentialDistributionGeneratorModel CreateInstance(ModelObjectType modelObjectType) {
			return new ExponentialDistributionGeneratorModel(modelObjectType);
		}


		protected internal ExponentialDistributionGeneratorModel(ModelObjectType modelObjectType)
			: base(modelObjectType)
        {
            this.terminalCount = 1;
		}


        protected internal ExponentialDistributionGeneratorModel(ExponentialDistributionGeneratorModel source)
			: base(source) {
            Variance = source.Variance;
            CropSize = source.CropSize;
            Translation = source.Translation;
            this.terminalCount = 1;
		}


		public override IModelObject Clone() {
            return new ExponentialDistributionGeneratorModel(this);
		}


		public override IEnumerable<MenuItemDef> GetMenuItemDefs() {
			throw new NotImplementedException();
		}


		public override void Connect(TerminalId ownTerminalId, IModelObject targetConnector, TerminalId targetTerminalId) {
			throw new NotImplementedException();
		}


		public override void Disconnect(TerminalId ownTerminalId, IModelObject targetConnector, TerminalId targetTerminalId) {
			throw new NotImplementedException();
		}

        public override char SecurityDomainName
        {
            get { return securityDomainName; }
            set
            {
                if (value < 'A' || value > 'Z')
                    throw new ArgumentOutOfRangeException("SecurityDomainName", "The domain qualifier has to be an upper case  ANSI letter (A-Z).");
                securityDomainName = value;
            }
        }


        #region IEntity Members

        public static new IEnumerable<EntityPropertyDefinition> GetPropertyDefinitions(int version)
        {
            foreach (EntityPropertyDefinition pi in ModelObjectBase.GetPropertyDefinitions(version))
                yield return pi;
            yield return new EntityFieldDefinition("Variance", typeof(double));
            yield return new EntityFieldDefinition("CropSize", typeof(double));
            yield return new EntityFieldDefinition("Translation", typeof(double));
        }

        protected override void LoadFieldsCore(IRepositoryReader reader, int version)
        {
            base.LoadFieldsCore(reader, version);
            Variance = reader.ReadDouble();
            CropSize = reader.ReadDouble();
            Translation = reader.ReadDouble();
        }

        protected override void SaveFieldsCore(IRepositoryWriter writer, int version)
        {
            base.SaveFieldsCore(writer, version);
            writer.WriteDouble(Variance);
            writer.WriteDouble(CropSize);
            writer.WriteDouble(Translation);
        }

        #endregion

    }
}
